package com.zusmart.base.looper.support;

import com.zusmart.base.logging.Logger;
import com.zusmart.base.logging.LoggerFactory;
import com.zusmart.base.looper.ThreadEventLoop;
import com.zusmart.base.looper.ThreadEventLoopGroup;
import com.zusmart.base.thread.FastThread;

public abstract class AbstractThreadEventLoop extends AbstractEventLoop implements ThreadEventLoop, Runnable {

	private static final Logger logger = LoggerFactory.getLogger(AbstractThreadEventLoop.class);

	private final FastThread monitor;

	private volatile boolean running = false;

	protected AbstractThreadEventLoop(String eventLoopName, ThreadEventLoopGroup eventLoopGroup) {
		super(eventLoopName, eventLoopGroup);
		this.monitor = new FastThread(this, eventLoopName);
	}

	@Override
	public ThreadEventLoopGroup getEventLoopGroup() {
		return (ThreadEventLoopGroup) super.getEventLoopGroup();
	}

	@Override
	protected void doStart() throws Exception {
		this.running = true;
		this.monitor.start();
	}

	@Override
	protected void doClose() throws Exception {
		this.running = false;
		this.doWake();
	}

	@Override
	public boolean isRunning() {
		return super.isRunning() && this.running;
	}

	@Override
	public void run() {
		for (; this.running;) {
			try {
				this.doLoop();
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(e.getMessage(), e);
			}
		}
		try {
			this.doStop();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	@Override
	public boolean inEventLoop() {
		return this.inEventLoop(Thread.currentThread());
	}

	@Override
	public boolean inEventLoop(Thread thread) {
		return thread == this.monitor;
	}

	@Override
	public Thread getMonitor() {
		return this.monitor;
	}

	protected void doWake() {

	}

	protected void doLoop() throws Exception {

	}

	protected void doStop() throws Exception {

	}

}